﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Net;
using System.Threading;
using System.ComponentModel;

namespace B13_Ex03_David_300512340_Alexey_321203689
{
    public delegate void ReportFinishedLoadingOnePhotoDelegate();

    public delegate void ReportFinishedLoadingPhotosDelegate();

    public delegate void ReportPhotoLoadingCanceledDelegate();

    public class AlbumFormLogic
    {
        public BackgroundWorker m_BackgroundWorkerLoader;
        private ReportFinishedLoadingOnePhotoDelegate m_ReportFinishedLoadingOnePhotoDelegate;
        private ReportFinishedLoadingPhotosDelegate m_ReportFinishedLoadingPhotosDelegate;
        private ReportPhotoLoadingCanceledDelegate m_ReportPhotoLoadingCanceledDelegate;

        public List<Image> ImagesList { get; private set; }

        public int ProgressBarValue { get; private set; }

        public AlbumFormLogic()
        {
            ImagesList = new List<Image>();
            initBackGroundWorker();
        }

        public void SaveAlbum(AlbumWrapper i_SelectedAlbum, string i_Path, string i_PictureName)
        {
            if (pathIsValid(i_Path))
            {
                i_SelectedAlbum.SaveAlbum(i_SelectedAlbum, i_Path, i_PictureName);
            }
        }

        public void SaveSelectedPhotos(string i_Path, string i_PictureName, ListBox i_ListBoxPictures)
        {
            int imageCounter = 1; // If there is more than one photo, number the photos.
            string photoName = i_PictureName == string.Empty ? "facebookImage" : i_PictureName;
            string fullPhotoName = i_ListBoxPictures.SelectedItems.Count == 1 ?
                photoName : string.Format("{0}{1}", photoName, imageCounter);

            if (pathIsValid(i_Path))
            {
                MessageBox.Show(null, "Saving photos, please wait.", "Save Photos", MessageBoxButtons.OK, MessageBoxIcon.Information);
                foreach (PhotoWrapper photo in i_ListBoxPictures.SelectedItems)
                {
                    photo.SavePhoto(photo, i_Path, fullPhotoName);
                    imageCounter++;
                    fullPhotoName = string.Format("{0}{1}", photoName, imageCounter);
                }

                MessageBox.Show(null, "Done saving photos.", "Save Photos", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void initBackGroundWorker()
        {
            m_BackgroundWorkerLoader = new BackgroundWorker();
            m_BackgroundWorkerLoader.WorkerReportsProgress = true;
            m_BackgroundWorkerLoader.WorkerSupportsCancellation = true;
            m_BackgroundWorkerLoader.DoWork += new DoWorkEventHandler(this.backgroundWorkerLoader_DoWork);
            m_BackgroundWorkerLoader.ProgressChanged += new ProgressChangedEventHandler(this.backgroundWorkerLoader_ProgressChanged);
            m_BackgroundWorkerLoader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.backgroundWorkerLoader_RunWorkerCompleted);
        }

        private void backgroundWorkerLoader_DoWork(object sender, DoWorkEventArgs e)
        {
            List<PhotoWrapper> photosList = e.Argument as List<PhotoWrapper>;
            int progressValue = 100 / photosList.Count;
            int progressValueReporter = 0;

            foreach (PhotoWrapper photo in photosList)
            {
                ImagesList.Add(getImageFromURL(photo.GetPhotoURL));
                progressValueReporter += progressValue;
                m_BackgroundWorkerLoader.ReportProgress(progressValueReporter);
                if (m_BackgroundWorkerLoader.CancellationPending)
                {
                    e.Cancel = true;
                    m_BackgroundWorkerLoader.ReportProgress(0);
                    return;
                }
            }

            m_BackgroundWorkerLoader.ReportProgress(100);
        }

        private void backgroundWorkerLoader_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressBarValue = e.ProgressPercentage;
            notifyFinishedLoadingOnePhotoToObservers();
        }

        private void backgroundWorkerLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                notifyPhotosLoadingCanceledToObservers();
            }
            else
            {
                notifyFinishedLoadingPhotosToObservers();
            }
        }

        #region AttachAndDetachObservers

        public void AttachObserver(ReportFinishedLoadingOnePhotoDelegate i_ObserverDelegate)
        {
            m_ReportFinishedLoadingOnePhotoDelegate += i_ObserverDelegate;
        }

        public void AttachObserver(ReportFinishedLoadingPhotosDelegate i_ObserverDelegate)
        {
            m_ReportFinishedLoadingPhotosDelegate += i_ObserverDelegate;
        }

        public void AttachObserver(ReportPhotoLoadingCanceledDelegate i_ObserverDelegate)
        {
            m_ReportPhotoLoadingCanceledDelegate += i_ObserverDelegate;
        }

        public void DetachObserver(ReportFinishedLoadingOnePhotoDelegate i_ObserverDelegate)
        {
            m_ReportFinishedLoadingOnePhotoDelegate -= i_ObserverDelegate;
        }

        public void DetachObserver(ReportFinishedLoadingPhotosDelegate i_ObserverDelegate)
        {
            m_ReportFinishedLoadingPhotosDelegate -= i_ObserverDelegate;
        }

        public void DetachObserver(ReportPhotoLoadingCanceledDelegate i_ObserverDelegate)
        {
            m_ReportPhotoLoadingCanceledDelegate -= i_ObserverDelegate;
        }

        #endregion

        private void notifyFinishedLoadingOnePhotoToObservers()
        {
            if (m_ReportFinishedLoadingOnePhotoDelegate != null)
            {
                m_ReportFinishedLoadingOnePhotoDelegate.Invoke();
            }
        }

        private void notifyFinishedLoadingPhotosToObservers()
        {
            if (m_ReportFinishedLoadingPhotosDelegate != null)
            {
                m_ReportFinishedLoadingPhotosDelegate.Invoke();
            }
        }

        private void notifyPhotosLoadingCanceledToObservers()
        {
            if (m_ReportPhotoLoadingCanceledDelegate != null)
            {
                m_ReportPhotoLoadingCanceledDelegate.Invoke();
            }
        }

        private Bitmap getImageFromURL(string i_StringURL)
        {
            HttpWebRequest myRequest;
            HttpWebResponse myResponse;

            myRequest = (HttpWebRequest)WebRequest.Create(i_StringURL);
            myRequest.Method = "GET";
            myResponse = (HttpWebResponse)myRequest.GetResponse();
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(myResponse.GetResponseStream());
            myResponse.Close();

            return bmp;
        }

        private bool pathIsValid(string i_Path)
        {
            return i_Path != string.Empty;
        }
    }
}
